<template>
  <div class="byted-weektime" @mousedown="dian" @mousemove="yi" @mouseup="li">
    <div class="calendar">
      <table class="calendar-table">
        <thead class="calendar-head">
          <tr>
            <th rowspan="6" colspan="2" class="week-td">星期 / 时间</th>
            <th colspan="6" class="font-bold">凌晨</th>
            <th colspan="6" class="font-bold">上午</th>
            <th colspan="6" class="font-bold">下午</th>
            <th colspan="6" class="font-bold">晚上</th>
          </tr>
          <tr style="border-bottom: none">
            <td
              v-for="(item, index) in tableHeader"
              :data-hour="Number(item)"
              class="w-[31px]"
              :key="index"
            >
              {{ Number(item) }}
            </td>
          </tr>
        </thead>
        <tbody>
          <div
            id="kuang"
            :style="{
              width: kuangObj.width + 'px',
              height: kuangObj.height + 'px',
              top: kuangObj.top + 'px',
              left: kuangObj.left + 'px',
              bottom: kuangObj.bottom + 'px',
              right: kuangObj.right + 'px',
            }"
          ></div>
          <tr>
            <td rowspan="5" class="font-bold w-[45px] border-t-0 leading-snug">
              工
              <br />
              作
              <br />
              日
            </td>
            <td class="border-t-0 bg-gray w-[45px]" data-week="0">周一</td>
            <td
              @mousedown.prevent="handleMouseDown(i, 0)"
              @mouseup.prevent="handleMouseUp(i, 0)"
              :data-week="0"
              :data-hour="i"
              class="calendar-atom-time"
              :class="item.class"
              v-for="(item, i) in rowUnit[0]"
              :key="i"
            ></td>
          </tr>
          <tr>
            <td data-week="1">周二</td>
            <td
              @mousedown.prevent="handleMouseDown(i, 1)"
              @mouseup.prevent="handleMouseUp(i, 1)"
              :data-week="1"
              :data-hour="i"
              class="calendar-atom-time"
              :class="item.class"
              v-for="(item, i) in rowUnit[1]"
              :key="i"
            ></td>
          </tr>
          <tr>
            <td data-week="2">周三</td>
            <td
              @mousedown.prevent="handleMouseDown(i, 2)"
              @mouseup.prevent="handleMouseUp(i, 2)"
              :data-week="2"
              :data-hour="i"
              class="calendar-atom-time"
              :class="item.class"
              v-for="(item, i) in rowUnit[2]"
              :key="i"
            ></td>
          </tr>
          <tr>
            <td data-week="3">周四</td>
            <td
              @mousedown.prevent="handleMouseDown(i, 3)"
              @mouseup.prevent="handleMouseUp(i, 3)"
              :data-week="3"
              :data-hour="i"
              class="calendar-atom-time"
              :class="item.class"
              v-for="(item, i) in rowUnit[3]"
              :key="i"
            ></td>
          </tr>
          <tr>
            <td data-week="4">周五</td>
            <td
              @mousedown.prevent="handleMouseDown(i, 4)"
              @mouseup.prevent="handleMouseUp(i, 4)"
              :data-week="4"
              :data-hour="i"
              class="calendar-atom-time"
              :class="item.class"
              v-for="(item, i) in rowUnit[4]"
              :key="i"
            ></td>
          </tr>
          <tr>
            <td rowspan="2" class="font-bold border-t-0 leading-snug">
              周
              <br />
              末
            </td>
            <td data-week="5" class="bg-gray">周六</td>
            <td
              @mousedown.prevent="handleMouseDown(i, 5)"
              @mouseup.prevent="handleMouseUp(i, 5)"
              :data-week="5"
              :data-hour="i"
              class="calendar-atom-time"
              :class="item.class"
              v-for="(item, i) in rowUnit[5]"
              :key="i"
            ></td>
          </tr>
          <tr>
            <td data-week="6">周日</td>
            <td
              @mousedown.prevent="handleMouseDown(i, 6)"
              @mouseup.prevent="handleMouseUp(i, 6)"
              :data-week="6"
              :data-hour="i"
              class="calendar-atom-time"
              :class="item.class"
              v-for="(item, i) in rowUnit[6]"
              :key="i"
            ></td>
          </tr>
        </tbody>
      </table>

      <div class="timeContent text-left flex">
        <div class="pr-7">已选时间</div>
        <div class="flex-1">
          <div class="pb-1" v-for="(w, index) in 7" :key="index">
            <span class="pr-5">{{ weekDate[String(index + 1)] }}</span>
            <span class="text-gray-400 dark:text-gray-100">
              {{ timeStr[index] || emptyText }}
            </span>
          </div>
        </div>
        <div class="flex-1">
          <div class="flex justify-end items-center">
            <el-button @click="clear" icon="RefreshRight" size="small">
              清空设置
            </el-button>
            <div class="flex items-center">
              <div class="ui-selected"></div>
              <span>投放时间段</span>
            </div>
            <div class="flex items-center">
              <div class="ui-selected ui-empty"></div>
              <span>不投放时间段</span>
            </div>
          </div>
          <div class="text-right text-base text-orange-300 pt-2">
            提示：请使用鼠标点选或拖动时间段
          </div>
        </div>
      </div>
    </div>
    <!-- 鼠标的画框的效果 -->
    <div
      :style="{
        backgroundColor: back,
        height: h + 'px',
        width: w + 'px',
        position: 'fixed',
        left: left + 'px',
        top: top + 'px',
        opacity: 0.2,
        border: len + 'px dashed #000',
        zIndex: 10,
        pointerEvents: 'none', //vue3版本没这个会影响时间选择
      }"
    ></div>
  </div>
</template>

<script setup>
import { onMounted, onBeforeUnmount, ref, watch, reactive, nextTick } from "vue"
// import {Position} from "@element-plus/icons-vue";

const props = defineProps({
  modelValue: {
    type: String,
    default: "",
  },
  emptyText: {
    type: String,
    default: "不投放",
  },
})

onMounted(() => {
  console.log(1)
  init()
})
const tableHeader = ref([
  "00",
  "01",
  "02",
  "03",
  "04",
  "05",
  "06",
  "07",
  "08",
  "09",
  "10",
  "11",
  "12",
  "13",
  "14",
  "15",
  "16",
  "17",
  "18",
  "19",
  "20",
  "21",
  "22",
  "23",
])

const weekDate = ref({
  1: "周一",
  2: "周二",
  3: "周三",
  4: "周四",
  5: "周五",
  6: "周六",
  7: "周日",
})

const rowUnit = ref([]) //每一个单元格
const timeContent = ref([]) //选中的时间段原始数据
const timeSection = ref([]) //时间段，可以返回给后台的数据
const timeStr = ref([]) //时间段，前端显示的数据
let beginDay = ref(0)
let beginTime = ref(0)
let downEvent = ref(false)

const emit = defineEmits(["update:modelValue"])
watch(
  () => rowUnit.value,
  (val) => {
    let timeRange = ""
    val.forEach((week, wIndex) => {
      timeRange += wIndex == 0 ? "" : "-"
      week.forEach((hour) => {
        timeRange += hour.class ? "1" : "0"
      })
    })
    emit("update:modelValue", timeRange)
    console.log(timeRange)
  },
  {
    deep: true,
  },
)

const kuangObj = ref({
  width: 0,
  height: 0,
  top: 0,
  left: 0,
  bottom: 0,
  right: 0,
  oldLeft: 0,
  oldTop: 0,
  flag: false,
})
let py = ref("")
let px = ref("")
let back = ref("var(--el-color-primary-light-1)")
let h = ref("")
let w = ref("")
let top = ref("")
let left = ref("")
let len = ref(0)

const init = () => {
  const timeRangeArr = props.modelValue.split("-")
  // console.log(timeRangeArr);
  for (let i = 0; i < 7; i++) {
    let arr = []
    let timeArr = timeRangeArr[i].split("")
    for (let j = 0; j < 24; j++) {
      let hourArr = timeArr[j]
      arr.push({
        class: hourArr == "1" ? "ui-selected" : null,
        timeData: j,
      })
      if (hourArr == "1") {
        setTimeout(() => {
          timeContent.value[i].arr.push(j)
          filterTime(i, j)
        }, 0)
      }
    }
    rowUnit.value.push(arr)
    timeContent.value.push({ arr: [] })
    timeSection.value.push([])
    timeStr.value.push("")
  }
}

const handleMouseDown = (i, day) => {
  downEvent.value = true //鼠标滑动不在范围内的不算
  beginDay.value = day
  beginTime.value = i
}

const dian = (event) => {
  px.value = event.pageX //获取x坐标
  py.value = event.pageY //获取y坐标
}

const yi = (event) => {
  if (px.value === "" || py.value === "") {
    return
  }
  let px1 = px.value
  let px2 = py.value
  left.value = event.pageX
  top.value = event.pageY
  h.value = top.value - py.value
  w.value = left.value - px.value
  let hc = -h.value
  let wc = -w.value
  len.value = 1
  back.value = "var(--el-color-primary-light-1)"
  if (h.value < 0 && w.value >= 0) {
    h.value = hc
    left.value = px1
  } else if (h.value >= 0 && w.value < 0) {
    w.value = wc
    top.value = px2
  } else if (h.value < 0 && w.value < 0) {
    h.value = hc
    w.value = wc
  } else {
    left.value = px.value
    top.value = py.value
  }
  if (w.value < 0) {
    w.value = 0 - w.value
  }
  if (h.value < 0) {
    h.value = 0 - h.value
  }
}

const li = () => {
  px.value = ""
  py.value = ""
  h.value = ""
  w.value = ""
  top.value = ""
  left.value = ""
  len.value = 0
  back.value = ""
}

const handleMouseUp = (i, day) => {
  console.log(i, day)
  let _this = this
  let begin = beginTime.value
  let start = begin <= i ? begin : i //x轴起点
  let length = Math.abs(begin - i)
  let end = start + length //x轴终点
  let dayStart = beginDay.value <= day ? beginDay.value : day //y轴 起点
  let dayLength = Math.abs(beginDay.value - day)
  let dayEnd = dayStart + dayLength //y轴终点

  const isAdd = () => {
    //当框选范围内所有块都是选中状态时,执行反选
    for (let x = dayStart; x < dayEnd + 1; x++) {
      for (let y = start; y < end + 1; y++) {
        if (rowUnit.value[x][y].class === null) return true
      }
    }
    return false
  }

  if (downEvent.value) {
    //当点击事件是在table内才触发选取数据操作
    if (isAdd()) {
      for (let x = dayStart; x < dayEnd + 1; x++) {
        for (let y = start; y < end + 1; y++) {
          if (rowUnit.value[x][y].class === null) {
            rowUnit.value[x][y].class = "ui-selected"
            timeContent.value[x].arr.push(rowUnit.value[x][y].timeData)
          }
        }
      }
    } else {
      for (let x = dayStart; x < dayEnd + 1; x++) {
        for (let y = start; y < end + 1; y++) {
          if (rowUnit.value[x][y].class === "ui-selected") {
            rowUnit.value[x][y].class = null
            let c = rowUnit.value[x][y].timeData
            let kong = ""
            for (let i = 0; i < timeContent.value[x].arr.length; i++) {
              if (c === timeContent.value[x].arr[i]) {
                kong = i
              }
            }
            // console.log(kong);
            timeContent.value[x].arr.splice(kong, 1)
          }
        }
      }
    }
    //过滤时间段,将临近的时间段合并
    console.log(dayStart, dayEnd)
    filterTime(dayStart, dayEnd)
  }
  downEvent.value = false
}

const filterTime = (start, end) => {
  const sortCut = (arr) => {
    //提取连续的数字
    let result = []
    arr?.forEach((v, i) => {
      let temp = result[result.length - 1]
      if (!i) {
        result.push([v])
      } else if (v % 1 === 0 && v - temp[temp.length - 1] === 1) {
        temp.push(v)
      } else {
        result.push([v])
      }
    })
    return result
  }

  const toStr = (num, minute = "00") => {
    //字符串时间段return
    // console.log(num)
    // if (Number.isInteger(num)) {
    let str = num < 10 ? "0" + num : num.toString()
    return str + ":" + minute
    // } else {
    //   let str = Math.floor(num) < 10 ? "0" + Math.floor(num) : Math.floor(num).toString();
    //   return str + ":30";
    // }
  }

  const timeToStr = (arr) => {
    //把数组转成字符串
    let str = ""
    arr.forEach((arr, index) => {
      let str1 = ""
      if (index === 0) {
        str1 = toStr(arr[0]) + "~" + toStr(arr[1], "59")
      } else {
        str1 = " , " + toStr(arr[0]) + "~" + toStr(arr[1], "59")
      }
      str += str1
    })
    return str
  }

  for (let i = start; i < end + 1; i++) {
    let arr1 = sortCut(timeContent.value[i]?.arr.sort((a, b) => a - b))
    let arr2 = []
    arr1.forEach((arr) => {
      let arr3 = []
      arr3.push(arr[0])
      arr3.push(arr[arr.length - 1])
      arr2.push(arr3)
    })
    timeStr.value[i] = timeToStr(arr2)
    timeSection.value[i] = arr2
  }
}

const clear = () => {
  rowUnit.value.forEach((item) => {
    item.forEach((item1) => {
      item1.class = null
    })
  })

  timeContent.value.forEach((item) => {
    item.arr = []
  })

  timeSection.value.forEach((item) => {
    item.length = 0
  })

  timeStr.value.length = 0
  for (let i = 0; i < 7; i++) {
    timeStr.value.push("")
  }
}
</script>

<style lang="scss" scoped>
.byted-weektime .calendar {
  position: relative;
  display: inline-block;

  //width: 820px;
  margin-top: 5px;
  -webkit-user-select: none;
}

/* .byted-weektime .calendar .schedule{background:#2F88FF;width:0;height:0;position:fixed;display:none;top:0;left:0;pointer-events:none;-webkit-transition:all 400ms ease;-moz-transition:all 400ms ease;-ms-transition:all 400ms ease;transition:all 400ms ease} */
.byted-weektime .calendar .calendar-table {
  width: 100%;
  border-collapse: collapse;
  border-radius: 4px;
}

.byted-weektime .calendar .calendar-table tr .calendar-atom-time {
  position: relative;
  border: none;

  &::before {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 5;
    width: 18px;
    height: 18px;
    cursor: pointer;
    content: "";
    border: 1px solid #e6e6e6;
    border-radius: 3px;
    transform: translate(-50%, -50%);
  }
}

.byted-weektime .calendar .calendar-table tr .ui-selected {
  &::before {
    background: var(--el-color-primary);
    border: none;
  }
}

.byted-weektime .calendar .calendar-table tr .ui-selected:hover {
  //&:after {
  //  content: "-";
  //}
}

.byted-weektime .calendar .calendar-table tr,
.byted-weektime .calendar .calendar-table td,
.byted-weektime .calendar .calendar-table th {
  font-size: 12px;
  line-height: 1;
  text-align: center;
  border: 1px solid #ccc;
  -webkit-transition: background 200ms ease;
  -moz-transition: background 200ms ease;
  -ms-transition: background 200ms ease;
  transition: background 200ms ease;

  &[data-week="0"] {
    height: 35px !important;
    padding-top: 3px;

    &::before,
    &::after {
      margin-top: 3px;
    }
  }

  &[data-week="6"] {
    height: 35px !important;
    padding-bottom: 3px;

    &::before,
    &::after {
      margin-top: -3px;
    }
  }

  &[data-hour="0"],
  &[data-hour="6"],
  &[data-hour="12"],
  &[data-hour="18"] {
    width: 35px !important;
    padding-left: 3px;
    border-left: 1px solid #eee;

    &::before,
    &::after {
      margin-left: 3px;
    }
  }

  &[data-hour="5"],
  &[data-hour="11"],
  &[data-hour="17"],
  &[data-hour="23"] {
    width: 35px !important;
    padding-right: 3px;

    &::before,
    &::after {
      margin-left: -3px;
    }
  }
}

.byted-weektime .calendar .calendar-table tbody tr {
  height: 33px;
  border-top: none;
  border-bottom: none;

  &:last-child {
    border-bottom: 1px solid #ccc;
  }
}

.byted-weektime .calendar .calendar-table tbody tr td {
  &:first-child,
  &.bg-gray {
    background: #f7f7f7 !important;

    &:is(.dark *) {
      background: transparent !important;
    }
  }
}

.byted-weektime .calendar .calendar-table thead th,
.byted-weektime .calendar .calendar-table thead td {
  height: 26px;
  background: #f7f7f7;

  &:is(.dark *) {
    background: transparent;
  }
}

.byted-weektime .calendar .calendar-table .td-table-tip {
  padding: 0 12px;
  line-height: 2.4em;
  background: #fff !important;

  &:is(.dark *) {
    background: transparent !important;
  }
}

.byted-weektime .calendar .calendar-table .td-table-tip .clearfix {
  height: 46px;
  line-height: 46px;
}

.byted-weektime .calendar .calendar-table .td-table-tip .pull-left {
  font-size: 14px;
  color: #999;

  &:is(.dark *) {
    color: #eee;
  }
}

.byted-weektime .week-td {
  width: 90px;
  min-width: 60px;
  padding: 20px 0;
  border-bottom: none !important;
}

.byted-weektime a {
  font-size: 14px;
  color: #2f88ff;
  cursor: pointer;
}

#kuang {
  position: absolute;
  background-color: blue;
  opacity: 0.3;
}

/* 将关闭按钮初始状态设置为隐藏 */
.closestyle {
  position: absolute;
  top: -10px;
  right: -12px;
  width: 20px;
  height: 20px;
  cursor: pointer;
  visibility: hidden; /* 初始隐藏 */
}

/* 鼠标悬停在日历上时显示关闭按钮 */
.calendar:hover .closestyle {
  visibility: visible; /* 悬停时显示 */
}

.closeicon {
  width: 20px;
  height: 20px;
  color: #fff;
}

.timeContent {
  padding-top: 12px;

  div,
  span {
    font-size: 14px;
    font-weight: normal;
    line-height: 1.8em;
    color: #444;

    &:is(.dark *) {
      color: #eee;
    }
  }

  .ui-selected {
    box-sizing: border-box;
    display: inline-block;
    width: 20px;
    height: 20px;
    margin-right: 10px;
    margin-left: 20px;
    vertical-align: middle;
    pointer-events: none;
    background: var(--el-color-primary);
    border: none;
    border-radius: 3px;

    &.ui-empty {
      background: transparent;
      border: 1px solid #e6e6e6;
    }
  }
}
</style>
